#include "StdAfx.h"
#include <iostream>
#include "umaths.h"
#include "ustringutils.h"
#include "CTPQuoteAdapter.h"
#include "ThostFtdcMdApi.h"
#include "MdHandler.h"
#include "tinyxml.h"
#include "tconfigsetting.h"

#include "loki/Singleton.h"

USING_LIBSPACE

CCTPQuoteAdapter::CCTPQuoteAdapter(void)
{
	m_papi = NULL;
	m_handler = NULL;
}

CCTPQuoteAdapter::~CCTPQuoteAdapter(void)
{
}


bool CCTPQuoteAdapter::Initialize( void* param )
{
	m_param =  CTPQuoteParamA::FromCTPQuoteParam( *   ((CTPQuoteParam*)param) );

	m_papi = CThostFtdcMdApi::CreateFtdcMdApi();
	m_handler = new CMdHandler(this);
	m_papi->RegisterSpi(m_handler);
	std::string addr =  m_param.Address + ":" + UStrConvUtils::ToStr( UStrConvUtils::ToString(m_param.Port) );

	m_papi->RegisterFront((char*)addr.c_str());
	m_papi->Init();

	WaitForReply();


	

	return true;
}

bool CCTPQuoteAdapter::ReqUserLogin()
{
	bool ret = false;
	CThostFtdcReqUserLoginField req = {0};
	
	strcpy(req.BrokerID, m_param.BROKER_ID.c_str());
	strcpy(req.UserID, m_param.INVESTOR_ID.c_str());
	strcpy(req.Password,m_param.PASSWORD.c_str());

	int iResult = m_papi->ReqUserLogin(&req, 1);
	

	return true;
}

bool CCTPQuoteAdapter::InitializeByXML( const TCHAR* pcfg )
{

	TConfigSetting setting;
	bool ret = setting.LoadConfig(pcfg);
	if(!ret)
		return ret;

	CTPQuoteParam param;
	std::string add = setting["configuration"]["saddress"].EleVal();
	param.Address = UStrConvUtils::ToTS(add);
	std::string port = setting["configuration"]["iport"].EleVal();
	param.Port = UMaths::ToInt32(port);
	param.BROKER_ID =  UStrConvUtils::ToTS(   setting["configuration"]["brokerid"].EleVal() );
	param.INVESTOR_ID =UStrConvUtils::ToTS(  setting["configuration"]["suserid"].EleVal() );
	param.PASSWORD = UStrConvUtils::ToTS(  setting["configuration"]["spassword"].EleVal() );

	ret = Initialize(&param);
	return ret;
}



bool CCTPQuoteAdapter::WaitForReply()
{
	return true;
}

void CCTPQuoteAdapter::UnInitialize()
{
	if(m_papi !=NULL)
	{
		CThostFtdcUserLogoutField field;
		strcpy ( field.BrokerID ,m_param.BROKER_ID.c_str());
		strcpy(field.UserID,m_param.INVESTOR_ID.c_str());
		m_papi->ReqUserLogout(&field,1);
		m_papi->Release();
		
		m_papi = NULL;
		
	}
	if(m_handler != NULL)
	{
		delete m_handler;
	}
	
}


bool CCTPQuoteAdapter::SubscribeQuote_CTP( const TCHAR* code,OnCTPQuoteRecieved callback )
{
	char* ppInstrumentID[1];
	char Key[32] = {0};
	strcpy(Key, UStrConvUtils::ToStr(code).c_str() );
	ppInstrumentID[0] = Key;
	if(m_papi != NULL)
	{	
		int ret = m_papi->SubscribeMarketData(ppInstrumentID,1);
		
		
		if( m_maps.GetMap().find(Key) != m_maps.GetMap().end() )
		{
			m_maps[Key] += callback;
		}
		else
		{
			m_maps[Key] = callback;
		}


		return true;
	}
	else
	{
		return false;
	}
	
}



void  CCTPQuoteAdapter:: UnSubscribeQuote_CTP( const TCHAR* Key,OnCTPQuoteRecieved callback )
{
	std::string key = UStrConvUtils::ToStr(Key);
	if(m_maps.GetMap().find(key) != m_maps.GetMap().end())
	{
		m_maps[key] -= callback;
	}
}

bool CCTPQuoteAdapter::GetLastError( std::pair<int,tstring>* perr )
{
	throw std::exception("The method or operation is not implemented.");
}
